<template>
    <div class="uploader-box">
        <!-- 图像展示 -->
        <template v-if="fileList.length > 0">
            <!-- 单图模式 -->
            <div class="avatar-box" v-if="fileList.length <= 1">
                <img :src="fileList[0].url" class="avatar" />
                <el-icon class="el-icon-close" @click="removeUpload(0)"><close /></el-icon>
            </div>

            <!-- 多图模式 -->
            <div class="uploader-list" v-else>
                <div class="avatar-box" v-for="(item, index) in fileList" :key="item.file">
                    <img :src="item.url" class="avatar" />
                    <el-icon class="el-icon-close" @click="removeUpload(index)">
                        <close />
                    </el-icon>
                </div>
            </div>
        </template>

        <!-- 上传组件 -->
        <template v-else>
            <el-upload
                class="avatar-uploader"
                action=""
                :limit="limit"
                :show-file-list="false"
                :before-upload="beforeUpload"
            >
                <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
        </template>
    </div>
</template>

<script>
import * as qiniu from 'qiniu-js';
import { defineComponent, getCurrentInstance, ref, toRefs, watch } from 'vue';

export default defineComponent({
    name: 'Uploader',
    props: {
        /**
         * 对应V-model
         */
        modelValue: {
            type: String,
            default: ''
        },
        /**
         * 允许最大上传个数
         */
        limit: {
            type: Number,
            default: 10
        },
        /**
         * 上传类型
         */
        fileType: {
            type: Array,
            default: () => ['images']
        },
        /**
         * 多图上传
         */
        multiple: {
            type: Boolean,
            default: false
        },
        /**
         * 上传成功回调
         */
        onSuccess: {
            type: Function,
            default: () => {}
        },
        /**
         * 删除操作回调
         */
        onRemove: {
            type: Function,
            default: () => {}
        }
    },
    setup(props, context) {
        const { proxy } = getCurrentInstance();
        let { multiple, onSuccess, onRemove } = toRefs(props);
        let fileList = ref([]);

        /**
         * 初始化组件数据
         */
        const init = (file) => {
            if (!multiple.value) {
                // 单图上传
                const fileObj = {
                    name: file,
                    url: proxy.$utils.splicingImageUrl(file)
                };

                fileList.value = [fileObj];
            } else {
                // 多图上传
                let fileArr = file.split(',');
                let list = [];

                list = fileArr.map((item) => ({
                    name: item,
                    url: proxy.$utils.splicingImageUrl(item)
                }));

                fileList.value = list;
            }
        };
        /**
         * 数据重置
         */
        const reset = () => {
            fileList.value = [];
        };

        // 上传处理
        const beforeUpload = (file) => {
            proxy.$utils.validateImg(file).then((status) => {
                if (status) {
                    proxy.$http.get(proxy.$config.upload.uploadToken).then((res) => {
                        let key = Date.now() + '_' + file.name;
                        let token = res.data.uploadToken;
                        let domain = res.data.domain;
                        let config = { useCdnDomain: true, region: null };
                        let putExtra = { fname: '', params: {}, mimeType: [] };
                        let observable = qiniu.upload(file, key, token, putExtra, config);

                        observable.subscribe({
                            next() {},
                            error() {},
                            complete(data) {
                                let image_url = 'http://' + domain + '/' + data.key;
                                const fileObj = {
                                    name: image_url,
                                    url: proxy.$utils.splicingImageUrl(image_url)
                                };
                                multiple.value
                                    ? fileList.value.push(fileObj)
                                    : (fileList.value = [fileObj]);

                                emitSuccess();
                            }
                        });
                    });
                }
            });
        };

        // 删除对应的file
        const removeUpload = (index) => {
            fileList.value.splice(index, 1);
            emitRemove();
        };

        // 上传回调处理
        const emitSuccess = () => {
            const fileStr = fileList.value.map((item) => item.name).join(',');
            onSuccess.value(fileStr, fileList);
        };

        // 删除回调处理
        const emitRemove = () => {
            const fileStr = fileList.value.map((item) => item.name).join(',');
            onRemove.value(fileStr, fileList);
        };

        watch(props, (newVal, oldVal) => {
            newVal.modelValue ? init(newVal.modelValue) : reset();
        });

        return {
            fileList,
            beforeUpload,
            removeUpload
        };
    }
});
</script>
